#pragma once

/// <summary>
/// BasicMesh: Interface for simple meshes, responsible for storing basic mesh data
/// <summary>

/**	Author: Dane Bulat
  * Created: 06/2013
  * Last Modified: 30/06/13
  * Version: v1.0
  */

// Includes
#include "IMesh.h"
#include "common/xnacollision.h"
#include "BasicShader.h"

// Class Definition
class BasicMesh : public IMesh
{
public:
//==============================
// Constructors / Destructors
//==============================

	/// Default Constructor
	BasicMesh();

  /**
	* Constructor 
	*
    * Constructor that takes material, texture and vertex and index buffer data 
	*
	* @param Vertex buffer data
	* @param Index buffer data
	* @param Material data
	* @param Diffuse map data
	* @param Boolean - does the mesh use a texture
	*/
	BasicMesh(ID3D11Buffer* vb, ID3D11Buffer* ib, Material* mat, ID3D11ShaderResourceView* dmap, bool texEnable);

  /**
	* Constructor 
	*
    * Constructor that takes material, texture and vertex and index buffer data, as well as rotation, translation and scale
	*
	* @param Vertex buffer data
	* @param Index buffer data
	* @param Material data
	* @param Diffuse map data
	* @param Translation value
	* @param Rotation value
	* @param Scale value
	* @param Texture transform value
	* @param Boolean - does the mesh use a texture
	*/
	BasicMesh(ID3D11Buffer* vb, ID3D11Buffer* ib, Material* mat, ID3D11ShaderResourceView* dmap, 
		XMFLOAT3& tran, XMFLOAT3& rot, XMFLOAT3& scale, XMFLOAT3& text, bool texEnable);

	/// Default Destructor
	~BasicMesh();

//==============================
// Get and Set Methods
//==============================

  /**
    * Set Axis Aligned Bounding Box 
	*
	* @param Pointer to box data
	*/
	void SetAABB(XNA::AxisAlignedBox* aabb);

  /**
    * Get Axis Aligned Bounding Box 
	*
	* @return Pointer to box data
	*/
	XNA::AxisAlignedBox* GetAABB() const;

  /**
    * Set ID of mesh instance
	*
	* @param String to set as ID
	*/
	void SetID(const string& id);				// ID Setter.

  /**
    * Get ID of mesh instance
	*
	* @return String ID
	*/
	string& GetID();							// ID Getter.
	
  /**
    * Set Translation of the mesh
	*
	* @param X Translation
	* @param Y Translation
	* @param Z Translation
	*/
	void SetTranslation(const float tx, const float ty, const float tz);

  /**
    * Get Translation of the mesh
	*
	* @return XMFLOAT3 containing translation data
	*/
	XMFLOAT3 GetTranslation() const;

  /**
    * Set Rotation of the mesh
	*
	* @param X Rotation
	* @param Y Rotation
	* @param Z Rotation
	*/
	void SetRotation(const float rx, const float ry, const float rz);

  /**
    * Set Scale of the mesh
	*
	* @param X Scale
	* @param Y Scale
	* @param Z Scale
	*/
	void SetScale(const float sx, const float sy, const float sz);
	
  /**
    * Set Texture Transform of the mesh
	*
	* @param X Texture Transform
	* @param Y Texture Transform
	* @param Z Texture Transform
	*/
	void SetTexTransform(const float sx, const float sy, const float sz);

  /**
    * Set Material of the mesh
	*
	* @param Pointer to material data
	*/
	void SetMaterial(Material* mat);

  /**
    * Set Diffuse map of the mesh
	*
	* @param Pointer to diffuse map
	*/
	void SetDiffuseMap(ID3D11ShaderResourceView* diffuse_map);

  /**
    * Set Texture Usage of the mesh
	*
	* @param Bool to toggle texture usage
	*/
	void EnableTexture(bool enable);

  /**
    * Set Vertex Buffer
	*
	* @param Pointer to vertex buffer
	*/
	void SetVertexBuffer(ID3D11Buffer* vb);

  /**
    * Set Index Buffer
	*
	* @param Pointer to index buffer
	*/
	void SetIndexBuffer(ID3D11Buffer* ib);

//==============================
// Update
//==============================

  /**
    * Update
	*
	* @param Delta Time since last frame
	*/
	void Update(float dt);

//==============================
// Draw
//==============================

  /**
    * Draw
	*
	* @param D3D Device Context
	* @param View Matrix
	* @param Projection Matrix
	*/
	void Draw(ID3D11DeviceContext* device_context, XMMATRIX& view, XMMATRIX& proj);

private:
	/// Private copy constructor
	BasicMesh(const BasicMesh&);			

	ID3D11Buffer*			  m_vertex_buffer;	///< Vertex Buffer
	ID3D11Buffer*			  m_index_buffer;   ///< Index Buffer
	ID3D11ShaderResourceView* m_diffuse_map;    ///< Diffuse Map

	string					  m_id;				///< Instance ID

	Material*				  m_material;		///< Material
	BasicShader*			  m_BasicShader;    ///< Pointer to basic shader for drawing

	XMFLOAT3				  m_translation;    ///< Translation data
	XMFLOAT3				  m_rotation;       ///< Rotation data
	XMFLOAT3				  m_scale;          ///< Scale data 
	XMFLOAT4X4				  m_tex_transform;  ///< Texture transform data

	UINT					  m_index_count;    ///< Number of Indices on model
	bool					  m_enable_texture; ///< Is the model textured
};